package cn1shared.net;

import java.io.InputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Arrays;


public class JsonServer extends JsonCon {
	private final Map<String,JsonCmd> cmds;
	public volatile boolean isRunning = true;
	private static final InputStream[] NO_INPUTS = new InputStream[0];
	private InputStream[] ins;

	public JsonServer(Map<String,JsonCmd> cmds,DataInputStream in,DataOutputStream out) {
		super(in,out);
		this.cmds = cmds;
	}

	public void setInputStreams(InputStream... ins) {
		this.ins = ins;
	}

	public void next() throws IOException {
		List<Object> request = receive();
		if( request.size() != 2 )
			throw new RuntimeException(request.toString());
		String cmdName = (String)request.get(0);
		Object arg = request.get(1);
		try {
			JsonCmd cmd = cmds.get(cmdName);
			if( cmd == null )
				throw new JsonCmdException(JsonErrorCode.CMD_NOT_FOUND,"command not found: "+cmdName,null);
			ins = NO_INPUTS;
			Object rtn = cmd.run(arg);
			List<Object> response = Arrays.asList(rtn);
			send(response,ins);
		} catch(JsonCmdException e) {
			List<Object> response = Arrays.asList( e.code, e.getMessage(), e.extra );
			send(response);
		} catch(RuntimeException e) {
			handleRuntimeException(e);
		}
	}

	public void handleRuntimeException(RuntimeException e) throws IOException {
		List<Object> response = Arrays.<Object>asList( JsonErrorCode.RUNTIME_EXCEPTION.toString(), e.toString(), null );
		send(response);
	}

	public void run() throws IOException {
		while( isRunning ) {
			next();
		}
	}
}
